﻿using System;
using System.ComponentModel;

namespace OpenLightGroup.Common.MVVM
{

    /// <summary>
    /// A ViewModel base class that provides some basic functionality common to most ViewModels.
    /// </summary>
    [CLSCompliant(true)]
    public abstract class BaseViewModel
        : INotifyPropertyChanged
    {

        #region INotifyPropertyChanged Members

        /// <summary>
        /// INotifyPropertyChanged.PropertyChanged event used to enable bindings to the properties of the ViewModel.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Helper method to handle raising the PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">The name of the property that has changed.</param>
        protected void RaisePropertyChanged(string propertyName)
        {
            this.PropertyChanged.Raise(this, propertyName);
        }

        #endregion

        #region Fields

        private Exception error;
        private bool hasChanges = false;
        private bool hasError = false;
        private bool isBusy = false;

        #endregion

        /// <summary>
        /// Raised when the Error property is set with an exception object.
        /// </summary>
        public event EventHandler ErrorOccurred;

        /// <summary>
        /// Holds a reference to an error that has occurred in the ViewModel. Can be used for basic error message display etc.
        /// </summary>
        public Exception Error
        {
            get { return error; }
            protected set
            {
                if (this.error != value)
                {
                    error = value;

                    this.RaisePropertyChanged("Error");

                    this.HasError = (value != null);

                    if (this.HasError)
                        this.ErrorOccurred.Raise(this);

                }
            }
        }

        /// <summary>
        ///  Indicates if the ViewModel has pending changes that need to be persisted.
        /// </summary>
        public bool HasChanges
        {
            get
            {
                return this.hasChanges;
            }
            protected set
            {
                if (this.hasChanges != value)
                {
                    this.hasChanges = value;
                    this.RaisePropertyChanged("HasChanges");
                }
            }
        }

        /// <summary>
        /// Indicates if the Error property has a reference to an exception object.
        /// </summary>
        public bool HasError
        {
            get
            {
                return this.hasError;
            }
            protected set
            {
                if (this.hasError != value)
                {
                    this.hasError = value;
                    this.RaisePropertyChanged("HasError");
                }
            }
        }

        /// <summary>
        /// Indicates the ViewModel is currently active, such as calling an asynchronous method.
        /// </summary>
        public bool IsBusy
        {
            get
            {
                return this.isBusy;
            }
            protected set
            {
                if (this.isBusy != value)
                {
                    this.isBusy = value;
                    this.RaisePropertyChanged("IsBusy");
                }
            }
        }

        /// <summary>
        /// Virtual method stub, no longer used.
        /// </summary>
        //[Obsolete("This method is no longer needed and will be removed.")]
        public virtual void UpdateIsBusy()
        {
        }

        /// <summary>
        /// Helper property that wraps DesignTimerHelper.IsRuntime
        /// </summary>
        protected bool IsRuntime
        {
            get
            {
                return DesignTimeHelper.IsRuntime;
            }
        }


    }
}
